package cn.superchart.web.core.config;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.superchart.common.enums.DeleteFlagEnum;
import cn.superchart.common.properties.SecurityProperties;
import cn.superchart.common.utils.Checker;
import cn.superchart.common.utils.ScUserContext;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectionException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.Date;


@Slf4j
@Configuration
public class GlobalConfig implements WebMvcConfigurer {


//    @Override
//    public void addResourceHandlers(ResourceHandlerRegistry registry) {
//        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
//        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
//        String uploadFileFolder;
//        DevConfigApi devConfigApi = SpringUtil.getBean(DevConfigApi.class);
//
//        if(SystemUtil.getOsInfo().isWindows()) {
//
//            /* 本地文件上传的位置 windows系统 */
//            String localFolderForWindows = devConfigApi.getValueByKey(SNOWY_FILE_LOCAL_FOLDER_FOR_WINDOWS_KEY);
//
//            if(ObjectUtil.isEmpty(localFolderForWindows)) {
//                throw new CommonException("本地文件操作客户端未正确配置：SNOWY_FILE_LOCAL_FOLDER_FOR_WINDOWS为空");
//            }
//            uploadFileFolder = localFolderForWindows;
//        } else {
//
//            /* 本地文件上传的位置 unix系列系统（linux、mac等） */
//            String localFolderForUnix = devConfigApi.getValueByKey(SNOWY_FILE_LOCAL_FOLDER_FOR_UNIX_KEY);
//
//            if(ObjectUtil.isEmpty(localFolderForUnix)) {
//                throw new CommonException("本地文件操作客户端未正确配置：SNOWY_FILE_LOCAL_FOLDER_FOR_UNIX为空");
//            }
//            uploadFileFolder = localFolderForUnix;
//        }
//        registry.addResourceHandler("/dev/file/**").addResourceLocations("file:" + uploadFileFolder + "//");
//    }



    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }

    @Component
    public static class CustomDbIdProvider implements DatabaseIdProvider {

        @Override
        public String getDatabaseId(DataSource dataSource) throws SQLException {
            Connection conn = null;
            try {
                conn = dataSource.getConnection();
                String url = conn.getMetaData().getURL().toLowerCase();
                if (url.contains("jdbc:oracle")) {
                    return "oracle";
                } else if (url.contains("jdbc:postgresql")) {
                    return "pgsql";
                } else if (url.contains("jdbc:mysql")) {
                    return "mysql";
                } else if (url.contains("jdbc:dm")) {
                    return "dm";
                } else if (url.contains("jdbc:kingbase")) {
                    return "kingbase";
                }  else {
                    return "mysql";
                }
            } finally {
                JdbcUtils.closeConnection(conn);
            }
        }
    }

    @Component
    public static class CustomMetaObjectHandler implements MetaObjectHandler {

        private SecurityProperties securityProperties;

        /** 删除标志 */
        private static final String DELETE_FLAG = "deleteFlag";

        /** 创建人 ID */
        private static final String CREATE_ID = "createId";

        /** 创建人 */
        private static final String CREATE_NAME = "createName";

        /** 创建时间 */
        private static final String GMT_CREATE = "gmtCreate";


        /** 更新人 ID */
        private static final String MODIFIED_ID = "modifiedId";

        /** 更新人 */
        private static final String MODIFIED_NAME = "modifiedName";

        /** 更新时间 */
        private static final String GMT_MODIFIED = "gmtModified";



        @Override
        public void insertFill(MetaObject metaObject) {
            try {
                //为空则设置 deleteFlag
                Object deleteFlag = metaObject.getValue(DELETE_FLAG);
                if (Checker.BeNull(deleteFlag)) {
                    setFieldValByName(DELETE_FLAG, EnumUtil.toString(DeleteFlagEnum.NOT_DELETE), metaObject);
                }
            } catch (ReflectionException e) {
                log.error("insertFill error:{}",e.getMessage());
            }
            try {
                //为空则设置 createId
                Object createName = metaObject.getValue(CREATE_ID);
                if (Checker.BeNull(createName)) {
                    setFieldValByName(CREATE_ID, this.getUserId(), metaObject);
                }
            } catch (ReflectionException e) {
                log.error("insertFill error:{}",e.getMessage());
            }

            try {
                //为空则设置 createName
                Object createName = metaObject.getValue(CREATE_NAME);
                if (Checker.BeNull(createName)) {
                    setFieldValByName(CREATE_NAME, this.getAccount(), metaObject);
                }
            } catch (ReflectionException e) {
                log.error("insertFill error:{}",e.getMessage());
            }
            try {
                //为空则设置 GMT_CREATE
                Object createTime = metaObject.getValue(GMT_CREATE);
                if (ObjectUtil.isNull(createTime)) {
                    setFieldValByName(GMT_CREATE, LocalDateTime.now(), metaObject);
                }
            } catch (ReflectionException e) {
                log.error("insertFill error:{}",e.getMessage());
            }
        }

        @Override
        public void updateFill(MetaObject metaObject) {
            try {
                //设置 modifiedId
                setFieldValByName(MODIFIED_ID, this.getUserId(), metaObject);
            } catch (ReflectionException e) {log.error("insertFill error:{}",e.getMessage()); }
            try {
                //设置 gmtModified
                setFieldValByName(GMT_MODIFIED, LocalDateTime.now(), metaObject);
            } catch (ReflectionException e) {log.error("insertFill error:{}",e.getMessage()); }

            try {
                //设置 modifiedName
                setFieldValByName(MODIFIED_NAME, this.getAccount(), metaObject);
            } catch (ReflectionException e) {log.error("insertFill error:{}",e.getMessage()); }
        }

        /**
         * 获取用户id
         */
        private String getUserId() {
            String userId =  ScUserContext.getUserId();
            return Checker.BeNotBlank(userId)?userId:"-1";
        }

        private String getAccount() {
            String account =  ScUserContext.getAccount();
            return Checker.BeNotBlank(account)?account:"-1";
        }
    }


//    @Resource
//    public void registerListenerList(List<CommonDataChangeListener> dataChangeListenerList) {
//        CommonDataChangeEventCenter.registerListenerList(dataChangeListenerList);
//    }
}
